﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using ProtoBuf.Message;

namespace Room
{
    public class NetUnionFightBase
    {

        /// 位置信息
        static public Dictionary<long, Vector3> postions = new Dictionary<long, Vector3>();
        //玩家朝向问题
        static public Dictionary<long, float> angles = new Dictionary<long, float>();
        /// 状态信息
        static public Dictionary<long, int> states = new Dictionary<long, int>();
        

        protected RoomUnionFight unionFight;
        protected RoomCharactorManager charactorManager;
        protected RoomNetUnionFight net;

        public event System.Action onRefreshData;
        
        public static bool Die(InstFightable fight)
        {
            var hp = 0.0;
            foreach(var _hp in fight.hpPos)
            {
                hp += _hp;
            }

            return hp <= 0.0;
        }

        public NetUnionFightBase(RoomUnionFight uf, RoomCharactorManager mgr,RoomNetUnionFight net)
        {
            this.unionFight = uf;
            this.charactorManager = mgr;
            this.net = net;
        }

        public virtual void Enter()
        {
            postions.Clear();
            states.Clear();
            angles.Clear();
        }

        public virtual void Leave()
        {
            postions.Clear();
            states.Clear();
            angles.Clear();
        }

        public virtual void Tick()
        {
#if !UNITY_EDITOR
            Time.timeScale = 1f;
#endif
        }
        public virtual void Resume()
        {

        }

        public virtual void Pause()
        {
        }
        
        public virtual RoomCharactor CreateCharactor(long uuid)
        {
            return null;
        }


        public void UpdateState(long uuid,int newState)
        {
            var charactor = GetCharactor(uuid);
            if (charactor != null)
            {
                states[uuid] = newState;
                charactor.ai.SwitchState(states[uuid]);
            }
            else
            {
                Debug.LogError("[Error] charactor is not find [" + uuid+"]");
            }
        }
        
        public void UpdateHp(long uuid,float hp)
        {
            var charactor = GetCharactor(uuid);
            if(charactor!=null)
            {
                charactor.ai.SetHp(hp);
            }
        }

        public void UpdateHp(InstFightable fight)
        {
            var maxHp = 0.0;
            var curHp = 0.0;
            foreach(var _maxHp in fight.maxHpPos)
            {
                maxHp += _maxHp;
            }   
            foreach(var _curHp in fight.hpPos)
            {
                curHp += _curHp;
            }

            if (maxHp == 0)
                maxHp = 1;

            var perHp =Mathf.Clamp01( (float)(curHp / maxHp) );
            var uuid = fight.guid;

            UpdateHp(uuid, perHp);
        }

        public void UpdateState(long uuid,int newState,object param)
        {
            var charactor = charactorManager.GetCharactor(uuid + "");
            if (charactor != null)
            {
                states[uuid] = newState;
                charactor.ai.SwitchState(states[uuid], param);
            }
            else
            {
                Debug.LogError("[Error] charactor is not find [" + uuid + "]");
            }
        }

        public void UpdateWordTip(long uuid,float hp)
        {
            var charactor = GetCharactor(uuid);
            if(charactor!=null)
            {
                var ai = charactor.ai as RCAIUnionFightBase;
                ai.ShowWordTip(charactor, (int)hp, hp > 0 ? WordType.ADD : WordType.DAMAGE);
            }
        }

        public void UpdatePosition(long uuid,Vector3 pos)
        {
            var charactor = GetCharactor(uuid+"");
            if (charactor != null)
            {
                postions[uuid] = pos;

                var nav = charactor.GetComponent<NavMeshAgent>();
                if (nav != null)
                {
                    if(RCMoveNavigation.SamplePosition(pos, out pos))
                    {
                        postions[uuid] = pos;
                    }
                    else
                    {
                        Debug.LogError("[ERROR] can't sample position!" + pos);
                    }
                }
                
                charactor.gameObject.SetActive(false);
                charactor.transform.position = postions[uuid];
                charactor.gameObject.SetActive(true);

            }
            else
            {
                Debug.LogError("[Error] charactor is not find [" + uuid + "]");
            }
        }

        public void UpdateAngle(long uuid, float angle)
        {
            var charactor = GetCharactor(uuid + "");
            if (charactor != null)
            {
                angles[uuid] = angle;
                charactor.transform.eulerAngles =new Vector3(0,angle,0);
            }
            else
            {
                Debug.LogError("[Error] charactor is not find [" + uuid + "]");
            }
        }

        public void UpdateBuff(InstUFBuff buff,long uuid)
        {
            var charactor = charactorManager.GetCharactor(uuid+"");
            if (charactor != null)
            {
                var ai = charactor.ai as RCAIUnionFightBase;
                ai.LoadBuff(buff);
            }
            else
            {
                Debug.LogError("[Error] charactor is not find [" + uuid + "]");
            }
        }

        public virtual void ClearCharactorData(long uuid)
        {
            if (postions.ContainsKey(uuid))
            {
                postions.Remove(uuid);
            }
            if (angles.ContainsKey(uuid))
            {
                angles.Remove(uuid);
            }
            if (states.ContainsKey(uuid))
            {
                states.Remove(uuid);
            }
        }

        public int GetState(long uuid)
        {
            if (states.ContainsKey(uuid))
                return states[uuid];
            else
            {
                Debug.LogError("[ERROR] uuid:" + uuid + " state not exist!");
                return 0;
            }
        }

        public Vector3 GetPosition(long uuid)
        {
            if (postions.ContainsKey(uuid))
                return postions[uuid];
            else
            {
                Debug.LogError("[ERROR] uuid:" + uuid + " position not exist!");
                return Vector3.one;
            }
        }

        public float GetAngle(long uuid)
        {
            if (angles.ContainsKey(uuid))
                return angles[uuid];
            else
            {
                Debug.LogError("[ERROR] uuid:" + uuid + " position not exist!");
                return 0;
            }
        }


        public RoomCharactor GetCharactor(long uuid,bool check=true)
        {
            return GetCharactor(uuid.ToString(),check);
        }

        public RoomCharactor GetCharactor(string uuid,bool check=true)
        {
            var charactor = charactorManager.GetCharactor(uuid);
            if(charactor==null && check)
            {
                long guid = 0L;
                if(long.TryParse(uuid, out guid))
                {
                    net.SendCSUFRefreshElement(guid);
                }
            }
            return charactor;
        }

        public List<RoomCharactor> GetCharactors(List<long> uuids)
        {
            var list = new List<RoomCharactor>();
            foreach (var uuid in uuids)
            {
                var charactor = GetCharactor(uuid);
                if (charactor == null)
                {
                    Debug.LogError("[ERROR] find null charactor [" + uuid + "]");
                }
                list.Add(charactor);
            }
            return list;
        }

        public void DestroyCharactor(long uuid)
        {
            DestroyCharactor(uuid + "");
        }
        public void DestroyCharactor(string uuid)
        {
            charactorManager.DestroyCharactor(uuid);
        }
        

        #region 刷新UI的接口
        public UI.UIUnionFightRunMap GetUI()
        {
            var page = UI.PageManager.Instance.GetDictPage("UIUnionFightRunMap") as UI.UIUnionFightRunMap;
            if (page != null)
                return page;
            throw new System.Exception("get current page is null");
        }

        public static RoomNetUnionFight GetNet()
        {
            var room = RoomManager.currentRoom as RoomUnionFight;
            if(room!=null)
            {
                var net = room.netManager;
                return net as RoomNetUnionFight;
            }

            return null;
        }
        #endregion
    }
}